import chalk from 'chalk';
import process from 'process';
import {spawn} from 'child_process';
import {createLogger} from '../utils/Logger.js';
import {CcSettings} from '../utils/CcSettings.js';

const logger = createLogger('CC');
const settingsStore = new CcSettings(logger);
const DEFAULT_CLAUDE_BIN = process.env.CC_CLAUDE_BIN || 'Claude';

export async function execute(args = []) {
    const [command, ...restArgs] = args;
    if (!command) {
        printHelp();
        return;
    }

    if (command === 'add') {
        await handleAdd(restArgs);
        return;
    }

    if (command === 'list') {
        await handleList();
        return;
    }

    await runProfile(command, restArgs);
}

function printHelp() {
    console.log(chalk.cyan('cc 命令使用方式:'));
    console.log('  cc add <名称> <Anthropic Base URL> <API Token>   新增配置');
    console.log('  cc list                                      查看配置列表');
    console.log('  cc <名称> [Claude 参数]                      以指定配置启动 Claude');
}

async function handleAdd(params) {
    if (params.length < 3) {
        logger.error('参数不足，请使用: cc add <名称> <Anthropic Base URL> <API Token>');
        process.exitCode = 1;
        return;
    }
    const [name, baseUrl, token] = params.map(item => item?.trim());
    if (!name || !baseUrl || !token) {
        logger.error('名称、Base URL 和 Token 均不能为空');
        process.exitCode = 1;
        return;
    }
    try {
        settingsStore.addProfile(name, baseUrl, token);
        logger.success(`配置 ${name} 写入 ~/.cc/settings.json 成功`);
    } catch (error) {
        if (error.code === 'DUPLICATE_PROFILE') {
            logger.error(`配置 ${name} 已存在，请使用其它名称`);
        } else {
            logger.error(`保存配置失败: ${error.message}`);
        }
        process.exitCode = 1;
    }
}

async function handleList() {
    const entries = settingsStore.listProfiles();
    if (entries.length === 0) {
        logger.warn('暂未配置任何 Claude 环境，可使用 cc add 新增');
        return;
    }
    console.log(chalk.green('当前可用配置:'));
    const rows = entries.map(([name, profile]) => ({
        名称: name,
        'Base URL': profile.baseUrl || '-/-',
        'Token(部分)': maskToken(profile.token),
        更新时间: formatTime(profile.updatedAt)
    }));
    console.table(rows);
}

async function runProfile(name, args) {
    const profile = settingsStore.getProfile(name);
    if (!profile) {
        logger.error(`配置 ${name} 暂未配置，可通过 cc add ${name} <BaseURL> <Token> 创建`);
        process.exitCode = 1;
        return;
    }
    if (!profile.baseUrl || !profile.token) {
        logger.error(`配置 ${name} 信息不完整，请重新执行 cc add ${name} <BaseURL> <Token>`);
        process.exitCode = 1;
        return;
    }
    const env = {
        ...process.env,
        ANTHROPIC_BASE_URL: profile.baseUrl,
        ANTHROPIC_AUTH_TOKEN: profile.token
    };
    logger.info(`已写入 ${name} 配置，准备启动 Claude`);
    try {
        const exitCode = await spawnClaude(env, args);
        if (exitCode === 0) {
            logger.success('Claude 已退出');
        } else {
            logger.error(`Claude 退出码: ${exitCode}`);
            process.exitCode = exitCode || 1;
        }
    } catch (error) {
        logger.error(`启动 Claude 失败: ${error.message}`);
        process.exitCode = 1;
    }
}

function spawnClaude(env, args) {
    return new Promise((resolve, reject) => {
        const child = spawn(DEFAULT_CLAUDE_BIN, args, {
            stdio: 'inherit',
            env,
            shell: process.platform === 'win32'
        });
        child.on('error', reject);
        child.on('exit', code => {
            resolve(typeof code === 'number' ? code : 0);
        });
    });
}

function maskToken(token = '') {
    const raw = token?.trim() ?? '';
    if (!raw) {
        return '未配置';
    }
    if (raw.length <= 6) {
        return `${raw[0] ?? ''}***`;
    }
    return `${raw.slice(0, 3)}***${raw.slice(-3)}`;
}

function formatTime(timeStr) {
    if (!timeStr) {
        return '-';
    }
    const date = new Date(timeStr);
    if (Number.isNaN(date.getTime())) {
        return timeStr;
    }
    return date.toLocaleString('zh-CN', {hour12: false});
}
